﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _8_Factory
{
    class Program
    {
        /*
          工厂模式：定义一个用于创建对象的接口，让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
          */
        static void Main(string[] args)
        {
            int type = 3;
            if (type == 1) //普通模式，客户端代码决定调用判断逻辑
            {
                LeiFeng student1 = new Undergraduate();
                student1.BuyRice();

                LeiFeng student2 = new Undergraduate();
                student1.Sweep();

                LeiFeng student3 = new Volunteer();
                student1.Wash();
            }
            else if (type == 2)
            {
                /*
                 * 简单工厂模式将 创建实体的分支判断逻辑从客户端抽离出来了。
                 * 对于客户端而 开放了变化,封闭了修改，需要新的实例去添加新的类和修改简单工厂类
                 * 但是对于简单工厂而言 依旧是要修改封闭逻辑 违背了开放封闭原则
                 */
                LeiFeng student1 = SimpleFactory.CreateLeifeng("大学生");
                student1.Sweep();

                //有相同的代码
                LeiFeng student2 = SimpleFactory.CreateLeifeng("社区自愿者");
                student2.Wash();
                LeiFeng student3 = SimpleFactory.CreateLeifeng("社区自愿者");
                student3.BuyRice();
            }
            else if (type == 3)
            {
                /* 使用工厂模式 
                   相对于简单工厂，克服了违背开放封闭原则的缺点，同时保持了简单工厂封装对象创建过程的有点。
                   它们都是集中封装了对象的创建，使得要更换对象时，不需要做大的改动就可以实现，降低客户程
                   序与产品对象的耦合。工厂方法模式是简单工厂模式的进一步抽象和推广。 由于使用了多态性，
                   工厂方法模式保持了简单工厂模式的优点，而且客服了它的缺点。 但是由于每加一个产品就要加一
                   个产品工厂的类，增加了额外的开发量。
                 */
                IFactory underFactory = new UndergraduateFactory();
                IFactory volunteerFactory = new UndergraduateFactory();
                LeiFeng student1 = underFactory.CreateLeiFeng();
                student1.Sweep();
                LeiFeng student2 = volunteerFactory.CreateLeiFeng();
                student2.Wash();
                LeiFeng student3 = volunteerFactory.CreateLeiFeng();
                student3.BuyRice();
            }

            Console.Read();
        }
    }
}
